#-*- coding:utf-8 -*-
'''
Created on Aug 31, 2012

@author: bbg
'''
import random, time, datetime
import dbwrapper
from dbwrapper.companyx.login_session import LoginSession
from dbwrapper.companyx.user import User
from dbwrapper.company_management.company import Company
from common.debug import Debug
import sqlalchemy.sql.expression
from sqlalchemy.orm import class_mapper

class LoginSessionManager(object):
    '''
        管理用户的登陆状态：
            step 1. 未登录用户用户登陆（用户名、密码），验证密码有效性，如果有效，生成这个token，下发这个token
            step 2. 已登陆用户（用户名，token），验证token有效性，有效则返回请求合法，否则请求不合法
    
    '''
    
    __session_valid_time__ = 36000 #session的有效时长，单位秒
    

    @staticmethod
    def generateToken():
        seeds = '1234567890!@#^*()ABCDEFGHIJKLMNOPJRSTUVSWXYZ'
        seeds_len = len(seeds)
        
        newToken = ''
        
        for i in range(4):
            for j in range(5):            
                idx = random.randint(0, seeds_len - 1)
                newToken = newToken + seeds[idx]
                time.sleep(0.001)
            if i < 3:
                newToken = newToken + '-'
            
        return newToken

    @staticmethod
    def login(company_id, username, pwd,dbsession):
        '''
            return value:
            (0, login token, user_id, shop_id)
            (-1, 'no such user')
            (-2, 'incorrect password')
            (-3, 'unknown reason, login failed') 
        '''
        #re-map login session table
      
        LoginSession.doMapping(company_id)
        User.doMapping(company_id)                 
        users = dbsession.query(User).filter(User.name == username)
        if users.count() == 0:
            return (-1, '用户不存在')
        
        user = users.first()
        if user.pwd != pwd:
            return (-2, '密码不正确')
        
        newToken = LoginSessionManager.__assignLoginSession(username,company_id,dbsession)
        if newToken is not None:
            return (0, newToken, user.id, user.shop_id,user.name,user.right_level,user.realname)
        
        return (-3, '失败 ')
    
    @staticmethod
    def __assignLoginSession(username,company_id,dbsession):
        '''
            return new token on success, else return None
        '''        
        inserted = False
        newToken = ''
        LoginSession.doMapping(company_id)
        loginSession=dbsession.query(LoginSession).filter(LoginSession.user_name == username)
        
        for row in loginSession:
            dbsession.delete(row)
            dbsession.commit()

        for i in range(3):
            newToken = LoginSessionManager.generateToken()
            loginSession = LoginSession()
            loginSession.user_name = username
            loginSession.token = newToken
            
            nowDate = datetime.datetime.now()
            loginSession.login_time = nowDate.strftime("%Y-%m-%d %H:%M:%S")
            #try:                
            dbsession.add(loginSession)
            dbsession.commit()
            #except:
            #    continue
            
            inserted = True
            break
                
        if inserted is True:
            return newToken
        else:
            return None
        
    @staticmethod
    def isValidSession(company_id, username, token, dbsession):
        '''
            validate session
        '''
        debug = Debug()
        LoginSession.doMapping(company_id)
        try:
            loginSessions = dbsession.query(LoginSession).filter(LoginSession.user_name == username).order_by(LoginSession.id.desc())
            dbsession.commit()
        except Exception, e:
            debug.e("LoginSessionManager:isValidSession, query session failed, %s, input token:%s" % (e, token))
            return False
        
        if loginSessions.count() == 0:
            debug.e("LoginSessionManager:isValidSession, no sunc login session, input token:%s" % token)
            return False
        
        loginSession = loginSessions.first()
        if loginSessions[0].token != token:
            debug.e("LoginSessionManager:isValidSession,token not match,input token:%s,should be %s" 
                    % (token, loginSessions[0].token))            
            return False
                   
        nowDate = datetime.datetime.now()
        lastUpdateDate = datetime.datetime.strptime(str(loginSession.login_time), "%Y-%m-%d %H:%M:%S")
        datethird = lastUpdateDate + datetime.timedelta(seconds=LoginSessionManager.__session_valid_time__)

        if nowDate > datethird:
            debug.e("LoginSessionManager:isValidSession,token expired, token:%s,nowDate:%s,lastUpdateDate:%s"
                     % (token, nowDate, lastUpdateDate))                        
            return False
       
        debug.d("LoginSessionManager:isValidSession, token:%s valid" % token)
        loginSession.login_time = nowDate.strftime("%Y-%m-%d %H:%M:%S")                      
               
        return True
    
    @staticmethod
    def isValidCompanyid(company_id,dbsession):
        '''
            validate company_id
        '''
        try:
            company=dbsession.query(Company).filter(Company.id == int(company_id))
            dbsession.commit()
        except:
            return False
        
        if company.count() == 0:
            return False
             
        return True



    def todictlistW(self,row):
        
        return   dict((col, getattr(row, col)) for col in row.__table__.columns.keys())
        return False

    @staticmethod
    def HasApplyed(name,yyzz,contact,phone,dbsession):
        '''
            validate apply
        '''
        try:
            debug=Debug()
            
            result_1 =dbsession.query(Company).filter(Company.name==name)
            result_2 =dbsession.query(Company).filter(Company.phone==phone)
            dicmy={}
            for r in result_1:
                dicmy=dict((col.name, getattr(r, col.name)) 
                           for col in (class_mapper(r.__class__).mapped_table.c)) 
                #for col in (class_mapper(r.__class__).mapped_table.c):
                #    debug.d("col.name:%s" % col.name)
                #debug.d("col.dicmy:%s" % dicmy)
                
                #for cc in row.__table__.columns:
                #    debug.d("row2dict:col:: %s: " % (cc.name))
                
                #dicmy={c.name: getattr(row, c.name) for c in row.__table__.columns} 
                #debug.d("row2dict:col:: %s: " % (dicmy))
                #for col in row.__table__.columns.keys():
                 #   debug.d("row2dict:col:%s: %s: " % (col,getattr(row, col)))
                    
                #row2dict = lambda row: {c.name: getattr(row, c.name) for c in row.__table__.columns}
                 
            #for column in result_1.__table__.columns:
            #    dicmy[column.name] = getattr(result_1[0], column.name) 
            #debug.d("dicmy:%s: " % repr(dicmy))
                
            dbsession.commit()
            result1cnt= result_1.count()
            result2cnt= result_2.count()
            if (result1cnt+result2cnt)>0 :      
                return True;
        except:
            return True
             
        return False
    
    @staticmethod
    def logout(company_id, username, token,dbsession):
        '''
            logout session
        '''
        LoginSession.doMapping(company_id)
        
        try:
            loginSessions = dbsession.query(LoginSession).filter(LoginSession.user_name == username)
            dbsession.commit()
        except:
            return False
        
        if loginSessions.count() == 0:
            return False
        
        loginSession = loginSessions.first()
        
        if loginSession.token != token:
            return False
        
        try:
            dbsession.delete(loginSession)
            dbsession.commit()
        except:
            return False
        
        return True
        

        